<?php

namespace app\task\cron\coupon;

use app\model\Agent;
use app\model\CouponOrder;
use app\model\FinanceDetail;
use app\model\TakeoutOrder;
use think\Exception;
use think\facade\Log;
use yunwuxin\cron\Task;
use think\facade\Db;
use app\common\model\FinanceStat;

/**
 * 外卖返佣
 *
 */
class SettleTakeoutOrder extends Task
{
    /**
     * 结算频率：每天凌晨结算一次
     */
    protected function configure()
    {
        // 分 时 日 月 周
        $this->expression = '* * * * *';
//        $this->expression = '0 1 * * *';
    }


    /**
     * 执行指令.
     */
    protected function handle()
    {
        echo '开始结算外卖' . PHP_EOL;
        $lockKey = 'takeout_order_profit_lock_key1';

//        $lockVal = cache($lockKey);
//        if ($lockVal) {
//            echo '还在处理呢' . PHP_EOL;
//            return true;
//        }

        cache($lockKey, 1, 1200);


        //临时方案
        //获取关联有美的所有id
        $agentIds = Agent::query()
            ->where('is_relation',Agent::IS_RELATION_YES)
            ->column('id');

//        if (isProd()){
            foreach (TAKEOUT_IDS as $agent_id) {
                array_push($agentIds,$agent_id);
            }
//        }


        $done = 0;

        $this->settleDateEdit($agentIds);

        TakeoutOrder::query()
            ->whereIn('agent_id',$agentIds)
            ->where('settle_at', '<', date('Y-m-d H:i:s'))
            ->where('settle_status', TakeoutOrder::SETTLE_STATUS_WAIT)
            ->select()->each(function (TakeoutOrder $takeoutOrder) {
                $balanceType = BALANCE_TACKOUT;
                if ($takeoutOrder->status != TakeoutOrder::STATUS_FINISH) {
                    $takeoutOrder->settle_status = TakeoutOrder::SETTLE_STATUS_NO;
                    $takeoutOrder->save();
                    Log::error('没有配置结算佣金记录类型');
                    return;
                }

                if ($takeoutOrder->profit <= 0) {
                    Log::error('金额为0 无需结算');
                    $takeoutOrder->settle_status = TakeoutOrder::SETTLE_STATUS_NO;
                    $takeoutOrder->save();
                    return;
                }
                // 防止重复结算
                $exists = Db::name('agent_balance_log')
                    ->where('type', $balanceType)
                    ->where('quote_id', $takeoutOrder->id)
                    ->value('id');
                if ($exists) {
                    $takeoutOrder->settle_status = TakeoutOrder::SETTLE_STATUS_FINISH;
                    $takeoutOrder->save();
                    return;
                }


                Db::startTrans();
                try {
                    $profitBalance = Db::name('agent')
                        ->where('id', $takeoutOrder->agent_id)
                        ->value('profit_balance');
                    Db::name('agent')
                        ->where('id', $takeoutOrder->agent_id)
                        ->inc('profit_balance', $takeoutOrder->profit)
                        ->inc('total_profit', $takeoutOrder->profit)
                        ->update([
                            'balance_last_updated_at' => date('Y-m-d H:i:s'),
                        ]);
                    Db::name('agent_balance_log')
                        ->insert([
                            'agent_id' => $takeoutOrder->agent_id,
                            'type' => $balanceType,
                            'amount' => $takeoutOrder->profit,
                            'old_balance' => $profitBalance,
                            'new_balance' => $profitBalance + $takeoutOrder->profit,
                            'remark' => '外卖 佣金结算：实际支付金额：' . fen2yuan($takeoutOrder->payprice) . '元，结算价：' . '元，利润：' . fen2yuan($takeoutOrder->profit) . '元。订单号：' . $takeoutOrder->order_id,
                            'quote_id' => $takeoutOrder->id,
                            'trade_no' => $takeoutOrder->order_id,
                        ]);


                    // 插入财务明细
                    FinanceStat::addSuccessRecord([
                        'order_id' => $takeoutOrder->order_id,
                        'order_type' => PRODUCT_METUAN_SERV,
                        'settle_type' => FinanceDetail::SETTLE_TYPE_CON,
                        'amount' => $takeoutOrder->payprice,
                        'sale_price' => $takeoutOrder->payprice,
                        'settle_price' => $takeoutOrder->payprice,
                        'supplier_price' => $takeoutOrder->payprice,
                        'profit' => $takeoutOrder->profit,
                        'platform_profit' => 0, //外卖平台不抽佣
                        'supplier_id' => 0, //暂无供应商
                        'agent_id' => $takeoutOrder->agent_id,
                        'salesman_id' => 0,
                        'remark' => '外卖佣金结算',
                    ]);

                    $takeoutOrder->settle_status = TakeoutOrder::SETTLE_STATUS_FINISH;
                    $takeoutOrder->save();

                    Db::commit();

                } catch (\Exception $e) {
                    Db::rollback();
                    echo '报错了吧：' . $e->getMessage() . PHP_EOL;
                }

            });


        cache($lockKey, null);

        echo '外卖结算结束：成功结算 ' . $done . ' 单' . PHP_EOL;
    }


    /**
     * 处理结算时间
     */
    public function settleDateEdit($agentIds)
    {

        TakeoutOrder::query()
            ->whereIn('agent_id',$agentIds)
            ->where('status', TakeoutOrder::STATUS_FINISH)
            ->where('settle_at', null)
            ->where('settle_status', TakeoutOrder::SETTLE_STATUS_NO)
            ->select()->each(function (TakeoutOrder $takeoutOrder) {
                //写入结算时间
                $takeoutOrder->settle_at = $this->getSettleDate(date('Y-m-d H:i:s', $takeoutOrder->paytime));
                $takeoutOrder->settle_status = TakeoutOrder::SETTLE_STATUS_WAIT;
                $takeoutOrder->save();
            });

    }

    /**
     * 根据支付时间，获取结算时间
     * 结算时间：次月25号
     */
    private function getSettleDate($payTime)
    {
        $year = substr($payTime, 0, 4);
        $month = substr($payTime, 5, 2) + 1;
        return date('Y-m-d', mktime(0, 0, 0, $month, 25, $year));
    }


}
